import re
import logging
import traceback
from typing import List, Dict, Any, Optional
from db.entity2 import MatchDataV2

# Configure logger
logger = logging.getLogger(__name__)

class BfDataParser:
    """
    解析 bfdata.js 数据的专用类
    基于数组 A[i] 的字段索引进行解析
    """

    def parse_js_content(self, js_content: str) -> Dict[str, Any]:
        """
        解析JS内容，返回包含 matches, leagues, countries 的字典
        """
        # 提取A数组（比赛数据）
        # 匹配 A[1]="..." 模式，忽略后续的 .split('^')
        a_matches = re.findall(r'A\[\d+\]\s*=\s*"([^"]+)"', js_content)
        
        # 提取B数组（赛事分类）
        b_leagues = re.findall(r'B\[\d+\]\s*=\s*"([^"]+)"', js_content)
        
        # 提取C数组（国家地区）
        c_countries = re.findall(r'C\[\d+\]\s*=\s*\[([^\]]+)\]', js_content)

        # 解析基础数据建立映射
        leagues_map = self._parse_leagues_to_map(b_leagues)
        countries_map = self._parse_countries_to_map(c_countries)

        # 解析比赛数据
        parsed_matches = []
        for m_str in a_matches:
            try:
                m_data = self._parse_single_match(m_str)
                
                # 补充关联数据
                if m_data.get('league_id') and m_data['league_id'] in leagues_map:
                    # bfdata.js A数组里已有联赛名，这里主要是为了验证或补充其他信息
                    pass 
                
                if m_data.get('country_id') and m_data['country_id'] in countries_map:
                    c_info = countries_map[m_data['country_id']]
                    m_data['country_name_simple'] = c_info.get('name_simple', '')
                    m_data['country_name_traditional'] = c_info.get('name_traditional', '')
                
                parsed_matches.append(m_data)
            except Exception as e:
                logger.error(f"Error parsing match string: {e}")

        return {
            'matches': parsed_matches,
            'leagues': list(leagues_map.values()),
            'countries': list(countries_map.values())
        }

    def _safe_get(self, arr: List[str], index: int, default: Any = '') -> Any:
        if index < len(arr):
            val = arr[index]
            return val if val != '' else default
        return default

    def _safe_int(self, arr: List[str], index: int, default: int = 0) -> int:
        val = self._safe_get(arr, index, default)
        try:
            return int(val)
        except (ValueError, TypeError):
            return default

    def _safe_float(self, arr: List[str], index: int, default: float = 0.0) -> float:
        val = self._safe_get(arr, index, default)
        try:
            return float(val)
        except (ValueError, TypeError):
            return default

    def _parse_single_match(self, match_str: str) -> Dict[str, Any]:
        """
        根据 bfdata.js 的 A 数组结构解析单场比赛
        """
        f = match_str.split('^')
        
        data = {}
        
        # 0: 赛事ID
        data['match_id'] = self._safe_get(f, 0)
        # 1: 颜色
        data['color'] = self._safe_get(f, 1)
        # 2: 联赛名(简)
        data['league_s'] = self._safe_get(f, 2)
        # 3: 联赛名(繁)
        data['league_t'] = self._safe_get(f, 3)
        # 4: 联赛名(英) - 部分为空
        
        # 5: 主队名(简)
        data['home_s'] = self._safe_get(f, 5)
        # 6: 主队名(繁)
        data['home_t'] = self._safe_get(f, 6)
        # 8: 客队名(简)
        data['away_s'] = self._safe_get(f, 8)
        # 9: 客队名(繁)
        data['away_t'] = self._safe_get(f, 9)
        
        # 11: 比赛时间 (短, e.g., 19:00)
        data['time_short'] = self._safe_get(f, 11)
        # 12: 比赛时间 (完整对象字符串, e.g., 2025,10,16,20,12,41)
        data['time_full'] = self._format_date(self._safe_get(f, 12))
        
        # 13: 状态
        data['state'] = self._safe_int(f, 13)
        
        # 14-15: 全场比分
        data['home_score'] = self._safe_int(f, 14)
        data['away_score'] = self._safe_int(f, 15)
        
        # 16-17: 半场比分
        data['home_half'] = self._safe_int(f, 16)
        data['away_half'] = self._safe_int(f, 17)
        
        # 18-19: 红牌
        data['home_red'] = self._safe_int(f, 18)
        data['away_red'] = self._safe_int(f, 19)
        
        # 20-21: 黄牌
        data['home_yellow'] = self._safe_int(f, 20)
        data['away_yellow'] = self._safe_int(f, 21)
        
        # 22-23: 排名
        data['home_rank'] = self._safe_get(f, 22)
        data['away_rank'] = self._safe_get(f, 23)
        
        # 28: 是否走地 (True/False)
        data['is_running'] = self._safe_get(f, 28).lower() == 'true'
        
        # 29: 亚盘盘口 (即时)
        data['handicap'] = self._safe_float(f, 29) if f[29] else None
        
        # 30: 说明/广告
        data['note'] = self._safe_get(f, 30)
        
        # 37-38: 球队ID
        data['home_id'] = self._safe_get(f, 37)
        data['away_id'] = self._safe_get(f, 38)
        
        # 40: 国家ID
        data['country_id'] = self._safe_get(f, 40)
        
        # 42: 说明/备注
        data['explain'] = self._safe_get(f, 42)
        
        # 45: 联赛ID
        data['league_id'] = self._safe_get(f, 45)
        
        # 48-49: 角球
        data['home_corner'] = self._safe_int(f, 48)
        data['away_corner'] = self._safe_int(f, 49)
        
        # 53: 高清直播 (1)
        data['has_live'] = self._safe_get(f, 53) == '1'
        
        # 62: 热门 (1)
        data['is_hot'] = self._safe_get(f, 62) == '1'
        
        return data

    def _parse_leagues_to_map(self, b_list: List[str]) -> Dict[str, Any]:
        # B[1]="西乙^西乙^^1^33^1^0^0^SubLeague.aspx?SclassID=33^546^1^0^0^0".split('^');
        l_map = {}
        for l_str in b_list:
            f = l_str.split('^')
            if len(f) > 4:
                lid = f[4]
                l_map[lid] = {
                    'id': lid,
                    'name_s': f[0],
                    'name_t': f[1]
                }
        return l_map

    def _parse_countries_to_map(self, c_list: List[str]) -> Dict[str, Any]:
        # C[0]=[3,'西班牙',0,'西班牙',0];
        c_map = {}
        for c_str in c_list:
            # remove [ ] and '
            clean_str = c_str.replace("'", "")
            f = [x.strip() for x in clean_str.split(',')]
            if len(f) >= 4:
                cid = f[0]
                c_map[cid] = {
                    'id': cid,
                    'name_simple': f[1],
                    'name_traditional': f[3]
                }
        return c_map

    def _format_date(self, raw_date: str) -> str:
        # 2025,10,16,20,12,41 -> 2025-10-16 20:12:41
        if not raw_date: return ''
        parts = raw_date.split(',')
        if len(parts) >= 6:
            return f"{parts[0]}-{parts[1].zfill(2)}-{parts[2].zfill(2)} {parts[3].zfill(2)}:{parts[4].zfill(2)}:{parts[5].zfill(2)}"
        return raw_date

    def convert_to_orm_objects(self, parsed_data: Dict[str, Any]) -> List[MatchDataV2]:
        """
        将解析的字典数据转换为 MatchDataV2 对象
        """
        objects = []
        for m in parsed_data.get('matches', []):
            # 合并说明字段
            note_full = m['note']
            if m['explain']:
                note_full = f"{note_full} | {m['explain']}" if note_full else m['explain']

            # 处理中立场地逻辑 (通常主队名包含(中))
            is_neutral = '(中)' in m['home_s']
            
            # 清理队名中的 (中)
            home_s = m['home_s'].replace('(中)', '')
            home_t = m['home_t'].replace('(中)', '')

            obj = MatchDataV2(
                比赛ID=m['match_id'],
                颜色=m['color'],
                联赛名_简体=m['league_s'],
                联赛名_繁体=m['league_t'],
                主队名_简体=home_s,
                主队名_繁体=home_t,
                客队名_简体=m['away_s'],
                客队名_繁体=m['away_t'],
                比赛时间=m['time_short'],
                比赛日期时间=m['time_full'],
                
                比赛状态=m['state'],
                主队比分=m['home_score'],
                客队比分=m['away_score'],
                主队半场比分=m['home_half'],
                客队半场比分=m['away_half'],
                
                主队红牌=m['home_red'],
                客队红牌=m['away_red'],
                主队黄牌=m['home_yellow'],
                客队黄牌=m['away_yellow'],
                主队角球=m['home_corner'],
                客队角球=m['away_corner'],
                
                主队排名=m['home_rank'],
                客队排名=m['away_rank'],
                
                是否中立场地=is_neutral,
                是否热门=m['is_hot'],
                是否走地=m['is_running'],
                是否有直播=m['has_live'],
                让球数=m['handicap'] if m['handicap'] is not None else 0.0,
                
                说明=note_full,
                
                联赛ID=m['league_id'],
                SCLASS_ID=m['league_id'],
                国家ID=m['country_id'],
                国家名_简体=m.get('country_name_simple', ''),
                国家名_繁体=m.get('country_name_traditional', '')
            )
            objects.append(obj)
        return objects

if __name__ == '__main__':
    # 简单的测试代码
    import os
    # 假设文件路径
    path = 'core/spider/html/bfdata.js'
    if os.path.exists(path):
        with open(path, 'r', encoding='utf-8') as f:
            content = f.read()
        
        parser = BfDataParser()
        result = parser.parse_js_content(content)
        print(f"Parsed {len(result['matches'])} matches")
        
        if result['matches']:
            print("Sample Match:", result['matches'][0])
            
        orm_objs = parser.convert_to_orm_objects(result)
        print(f"Converted {len(orm_objs)} ORM objects")